import { queenWatcher } from './scheduler'
import { pushTarget, popTarget } from './dep'
let id = 1
class Watcher{
    constructor(vm,exprOrFn,cb,options){
        this.id = id++
        this.vm = vm
        this.cb = cb 
        this.options = options
        // this.getter = exprOrFn

        this.user = !!options.user // 代表是watch
        this.lazy = options.lazy // 代表是computed
        this.dirty = this.lazy // true时computed取值，false时走老值

        this.depIds = new Set()
        this.deps = []

        if(typeof exprOrFn === 'string'){
            this.getter = function(){
               let obj = vm
               let path = exprOrFn.split('.')
               for(let i = 0; i < path.length; i++){
                   obj = obj[path[i]]
               }
               return obj
            }
        }else{
            this.getter = exprOrFn
        }
        this.value = this.lazy ? undefined : this.get()
    }
    get(){
        pushTarget(this)
        const value = this.getter()
        popTarget()
        return value
    }
    addDep(dep){
        if(!this.depIds.has(dep.id)){
            this.depIds.add(dep.id)
            this.deps.push(dep)
            dep.addSub(this)
        }
    }
    update(){
        if(this.lazy){
           this.dirty = true
        }else{
           queenWatcher(this) 
        }
    }
    run(){
        const oldVal = this.value
        this.value = this.get()
        if(this.user){
            this.cb.call(this.vm, this.value, oldVal)
        }
    }
    evaluate(){
        this.dirty = false
        this.get()
    }
}

export default Watcher